<?php


namespace App\Services;



use App\Exceptions\ApiException;
use App\Models\Admin;
use App\Models\AuthGroup;
use App\Models\AuthGroupAccess;
use Firebase\JWT\BeforeValidException;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\JWT;
use Firebase\JWT\SignatureInvalidException;
use Illuminate\Support\Facades\Hash;

class AdminService
{

    private static $adminInfo;

    /**
     * 添加管理员
     * @param $data
     */
    public function add(array $data)
    {
        $admin=Admin::where('account',$data['account'])->first();
        if (!empty($admin)){
            throw new ApiException(20001);
        }
        $admin =new Admin();
        $admin->account = $data['account'];
        $admin->name = $data['name'];
        $admin->password = Hash::make($data['password']);
        $admin->save();
    }


    /**
     * 修改管理员
     * @param array $data
     * @throws OperateException
     */
    public function edit(array $data){
        $admin=Admin::find($data['id']);
        if (empty($admin)){
            throw new ApiException(30001);
        }
        //判断重复
        $r=Admin::where('account',$data['account'])
            ->where('id','<>',$data['id'])
            ->get();
        if (!$r->isEmpty()){
            throw new ApiException(20001);
        }
        $admin->account = $data['account'];
        $admin->name = $data['name'];
        $result =$admin->save();
        if (!$result){
            throw new ApiException(30002);
        }
    }

    /**
     * 删除指定管理员
     * @param int $id
     * @throws \Exception
     */
    public function del(int $id){
        $admin=Admin::find($id);
        if (empty($admin)) {
            throw new ApiException(30001);
        }
        $admin->delete();
    }

    /**
     * 管理员列表
     * @param int $limit
     * @return mixed
     */
    public function page($limit=15){
        $page = Admin::select(['id','account','name','created_at'])->paginate($limit);
        return ['count'=>$page->total(),'data'=>$page->items()];
    }

    /**
     * 获取管理员的权限id
     * @param int $adminId
     * @return bool|false|string[]
     */
    public function getRulesByAdminId(int $adminId){
        $groupIds = AuthGroupAccess::where('admin_id',$adminId)->value('group_ids');
        if (empty($groupIds)){
            return false;
        }

        $rules = AuthGroup::whereIn('id',explode(',',$groupIds))->pluck('rules')->toArray();
        if (empty($rules)){
            return  false;
        }
        $ruleIds = implode(',',$rules);
        return array_unique(explode(',',$ruleIds));
    }

    /**
     * 权限检测
     * @param int $adminId
     * @param $ruleId
     * @throws OperateException
     */
    public function checkAuth(int $adminId,$ruleId){
        $ruleIds = $this->getRulesByAdminId($adminId);
        if (!$ruleIds){
            throw new ApiException(50001);
        }

        if (!in_array($adminId,$ruleIds)){
            throw new ApiException(50001);
        }

    }

    /**
     * 登录
     * @param $account
     * @param $password
     * @param $
     */
    public function login($account,$password,$ip){
        $admin = Admin::where('account',$account)->select('id','password','name','last_login_at','last_login_ip')->first();
        if (empty($admin)){
            throw new ApiException(20002);
        }
        if (!Hash::check($password,$admin->password)){
            throw new OperateException(20003);
        }

        $key =env('JWT_KEY');
        $exp = env('JWT_EXP');
        //设置载荷
        $payload = [
            'iss'=> 'letsadmin',
            'iat'=> time(),//jwt的签发时间
            'exp'=> time()+$exp,//过期时间
            'nbf'=> time(),//此时间之前无效
            'jti'=> uniqid(),//唯一身份标识
            'data'=>[
                'id'=> $admin->id,
                'name'=> $admin->name,
                'last_login_at'=> date('Y-m-d H:i:s',$admin->last_login_at),
                'last_login_ip'=> $admin->last_login_ip,
            ]
        ];
        $token = JWT::encode($payload,$key);

        //更新登录信息
        $admin->last_login_at = time();
        $admin->last_login_ip = $ip;
        $admin->save();

        return $token;
    }

    /**
     * token验证
     * @param string $token
     * @return object|null
     * @throws OperateException
     */
    public function auth(string $token){
        $key =env('JWT_KEY');
        [,$token] = explode(' ',$token);

        try {
            $decoded = JWT::decode($token, $key, array('HS256'));
            $this->setInfo($decoded->data);
        }catch (UnexpectedValueException $e){
            throw new ApiException(40002);
        }catch (SignatureInvalidException $e){
            throw new ApiException(40003);
        }catch (BeforeValidException $e){
            throw new ApiException(40002);
        }catch (ExpiredException $e){
            throw new ApiException(40004);
        }catch (\Exception $e){
            throw new ApiException(40002);
        }
        return $decoded;
    }

    //设置当前登录管理员信息
    private function setInfo(object $data){
        if (empty($data)){
            throw new OperateException(40002);
        }
        self::$adminInfo = $data;
    }

    //获取当前登录管理员信息
    public function info(){
        return self::$adminInfo;
    }








}
